import {
  Injectable,
  NotFoundException,
  ConflictException,
} from '@nestjs/common';
import { PrismaService } from '../prisma/prisma.service';
import * as bcrypt from 'bcrypt';
import { JwtService } from '@nestjs/jwt'; // 导入 JwtService
import { ApiResponse } from 'src/common/reponse.interface'; // 引入统一响应格式
import { CreateUserDto } from './create-user.dto'; // 引入 DTO

@Injectable()
export class UsersService {
  constructor(
    private prisma: PrismaService,
    private jwtService: JwtService, // 注入 JwtService
  ) {}

  // 创建用户
  async create(createUserDto: CreateUserDto): Promise<ApiResponse<any>> {
    const { username, password, roleId } = createUserDto;
    if (!roleId) {
      throw new Error('查询不到用户id');
    }

    // 检查用户名是否已经存在
    const existingUser = await this.prisma.user.findUnique({
      where: { username },
    });

    if (existingUser) {
      throw new ConflictException('用户名已存在');
    }

    if (!password || password.trim().length === 0) {
      throw new Error('Password cannot be empty');
    }

    const hashedPassword = await bcrypt.hash(password, 10); // 加密密码

    const user = await this.prisma.user.create({
      data: {
        username,
        password: hashedPassword,
        role: {
          connect: { id: roleId }, // 通过 roleId 关联角色
        },
      },
    });

    // 生成 JWT
    const payload = { sub: user.id, username: user.username };
    const token = await this.jwtService.sign(payload); // 使用 sign 方法生成 JWT
    // 返回统一响应格式
    return {
      statusCode: 201,
      message: '用户创建成功',
      data: { user: { id: user.id, username: user.username }, token },
    }; // 返回用户和 JWT
  }

  async findOne(usernameOrId: string | number): Promise<ApiResponse<any>> {
    // 添加条件来查询数据库，确保查询的字段是正确的
    const whereCondition =
      typeof usernameOrId === 'string'
        ? { username: usernameOrId } // 查找用户名
        : { id: usernameOrId }; // 查找用户ID

    // 查询用户及其角色和菜单
    const user = await this.prisma.user.findFirst({
      where: whereCondition,
      include: {
        role: {
          include: {
            menus: {
              select: {
                menu: true, // 选择菜单数据
              },
            },
          }, // 包含角色信息及其菜单
        },
        images: true,
      },
    });

    if (!user) {
      throw new NotFoundException('没有查询到用户');
    }

    // 返回用户信息和可访问的菜单
    return {
      statusCode: 200,
      message: '用户信息查询成功',
      data: {
        id: user.id,
        username: user.username,
        role: user.role, // 包含角色信息
        image: user.images,
      },
    };
  }

  // 更新用户
  async update(
    usernameOrId: string | number,
    oldPassword: string,
    newPassword: string,
    roleId: number,
  ): Promise<ApiResponse<any>> {
    // 查找用户信息，注意这里不包含密码
    const existingUser = await this.findOne(usernameOrId);

    // 获取用户的当前密码（仅用于验证）
    const userWithPassword = await this.prisma.user.findUnique({
      where: { id: existingUser.data.id },
      select: { password: true }, // 仅获取密码
    });

    // 如果密码不为空，则更新密码
    let hashedPassword = userWithPassword.password;
    if (oldPassword && oldPassword.trim().length > 0) {
      // 获取用户的当前密码（仅用于验证），加密新密码
      const user = await this.prisma.user.findUnique({
        where: { id: existingUser.data.id },
        select: { password: true }, // 仅获取密码
      });

      const isPasswordValid = await bcrypt.compare(oldPassword, user.password);
      if (!isPasswordValid) {
        throw new NotFoundException('密码错误');
      }

      hashedPassword = await bcrypt.hash(newPassword, 10); // 加密新密码
    }

    const updatedUser = await this.prisma.user.update({
      where: { id: existingUser.data.id },
      data: {
        password: hashedPassword,
        role: {
          connect: { id: roleId },
        },
      },
    });

    return {
      statusCode: 200,
      message: '用户更新成功',
      data: {
        id: updatedUser.id,
        username: updatedUser.username,
      },
    }; // 返回用户基本信息
  }

  // 删除用户
  async delete(usernameOrId: string | number): Promise<ApiResponse<any>> {
    const existingUser = await this.findOne(usernameOrId); // 根据用户名或ID查找用户

    await this.prisma.user.delete({
      where: { id: existingUser.data.id },
    });

    return {
      statusCode: 200,
      message: '用户删除成功',
      data: null,
    };
  }

  // 获取全部
  async findAll(): Promise<ApiResponse<any>> {
    const users = await this.prisma.user.findMany({
      include: {
        role: {
          include: {
            menus: true,
          },
        }, // 获取角色的所有菜单
      },
    });
    if (!users || users.length === 0) {
      throw new NotFoundException('没有找到任何用户');
    }
    const result = users.map((user) => ({
      id: user.id,
      username: user.username,
      role: {
        id: user.role.id,
        name: user.role.name,
      },
    }));
    return {
      statusCode: 200,
      message: '用户信息查询成功',
      data: result,
    };
  }

  // 获取用户菜单

  async getUserMenu(userId: number): Promise<ApiResponse<any>> {
    // 查找用户和用户对应的角色以及该角色的菜单
    const user = await this.prisma.user.findUnique({
      where: {
        id: userId,
      },
      include: {
        role: {
          include: {
            menus: true,
          },
        },
      },
    });

    if (!user) {
      throw new NotFoundException('没有该用户');
    }

    const result = await Promise.all(
      user.role.menus.map(async (roleMenu) => {
        const menu = await this.prisma.menu.findUnique({
          where: { id: roleMenu.menuId }, // 根据 menuId 查找菜单
        });
        return { name: menu?.name };
      }),
    );

    return {
      statusCode: 200,
      message: '用户信息查询成功',
      data: result,
    };
  }
}
